package com.rc.saas.tenant.service.elec;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rc.saas.tenant.common.utils.DateHelper;
import com.rc.saas.tenant.common.utils.NumberUtil;
import com.rc.saas.tenant.common.utils.StringUtil;
import com.rc.saas.tenant.common.vo.TResponse;
import com.rc.saas.tenant.mapper.elec.ElecGunMapper;
import com.rc.saas.tenant.mapper.order.OrderInfoMapper;
import com.rc.saas.tenant.model.elec.*;
import com.rc.saas.tenant.model.order.OrderInfo;
import com.rc.saas.tenant.redis.RedChargeDataService;
import com.rc.saas.tenant.search.StatisticsSearch;
import com.rc.saas.tenant.search.elec.ElecGunSearch;
import com.rc.saas.tenant.service.tenant.TenantRoleService;
import com.rc.saas.tenant.vo.elec.ElecPileStatusCountVo;
import com.rc.saas.tenant.vo.gun.ElecGunMonitorChartVo;
import com.rc.saas.tenant.vo.gun.ElecGunMonitorVo;
import com.rc.saas.tenant.vo.order.OrderInfoMonitorVo;
import com.rc.saas.tenant.vo.order.OrderResult;
import com.rc.saas.tenant.vo.tenant.TenantUserRoleVo;
import groovy.lang.Lazy;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by yang on 2022-04-17
 */
@Service
public class ElecGunServiceImpl implements ElecGunService {
    @Autowired
    private ElecGunMapper elecGunMapper;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private RedChargeDataService redChargeDataService;

    @Autowired
    @Lazy
    private ElecPileService elecPileService;

    @Autowired
    private TenantRoleService tenantRoleService;

    @Override
    public ElecGunMapper getMapper() {
        return elecGunMapper;
    }

    @Override
    public void updateGunStatus(Long elecGunId) {
        ElecGun elecGun = elecGunMapper.selectByPrimaryKey(elecGunId);
        if ("1".equals(elecGun.getOperateStatus())) {
            elecGun.setOperateStatus("2");
        } else if ("2".equals(elecGun.getOperateStatus())) {
            elecGun.setOperateStatus("1");
        }
        elecGunMapper.updateByPrimaryKeySelective(elecGun);
    }

    @Override
    public long countUseGun(String tenantCode) {
        long useGuncount = elecGunMapper.countUseGun(tenantCode);
        return useGuncount;
    }

    @Override
    public long countGun(String tenantCode) {
        long gunCount = elecGunMapper.countGun(tenantCode);
        return gunCount;
    }

    @Override
    public ElecGun selectByOperatorIdAndGunNo(String tenantCode, String hlhtOperatorId, String hlhtGunNo) {
        ElecGunExample example = new ElecGunExample();
        example.createCriteria().andTenantCodeEqualTo(tenantCode).andHlhtOperatorIdEqualTo(hlhtOperatorId).andHlhtGunNoEqualTo(hlhtGunNo);
        List<ElecGun> list = elecGunMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<ElecGun> listGunByPileId(Long pileId) {
        ElecGunExample example = new ElecGunExample();
        example.createCriteria().andElecPileIdEqualTo(pileId);
        List<ElecGun> elecGuns = elecGunMapper.selectByExample(example);
        return elecGuns;
    }

    @Override
    public PageInfo<ElecGun> listPageByCondition(ElecGunSearch elecGunSearch) {
        TenantUserRoleVo userRoleVo = tenantRoleService.getLonginRole(elecGunSearch.getLoginName());
        if (userRoleVo!=null){
            elecGunSearch.setRoleType(userRoleVo.getRoleType());
            elecGunSearch.setDataAuth(userRoleVo.getDataAuth());
            switch (userRoleVo.getRoleType()){
                case "1"://自定义用户
                    elecGunSearch.setOperatorIds(
                            StringUtils.isNotBlank(userRoleVo.getOperatorIds())?
                                    Arrays.asList(userRoleVo.getOperatorIds().split(","))
                                    :new ArrayList<String>());
                    elecGunSearch.setEnterpriseIds(
                            StringUtils.isNotBlank(userRoleVo.getEnterpriseIds())?
                                    Arrays.asList(userRoleVo.getEnterpriseIds().split(","))
                                    :new ArrayList<String>());
                    break;
                case "2"://加盟商用户
                    elecGunSearch.setOperatorIds(StringUtils.isNotBlank(userRoleVo.getOperatorIds())?
                            Arrays.asList(userRoleVo.getOperatorIds().split(","))
                            :new ArrayList<String>());
                    break;
                case "3"://企业用户
                    elecGunSearch.setEnterpriseIds(StringUtils.isNotBlank(userRoleVo.getEnterpriseIds())?
                            Arrays.asList(userRoleVo.getEnterpriseIds().split(","))
                            :new ArrayList<String>());
                    break;
            }
        }
        PageHelper.startPage(elecGunSearch.getOffset(), elecGunSearch.getLimit());
        List<ElecGun> elecGuns = elecGunMapper.listByCondition(elecGunSearch);
        return new PageInfo<ElecGun>(elecGuns);
    }

    @Override
    public void updateBatchElecGunOperateStatusByElecStationIdList(List<Long> elecStationIdList, String operateStatus) {
        elecGunMapper.updateBatchElecGunOperateStatusByElecStationIdList(elecStationIdList, operateStatus);
    }

    @Override
    public List<ElecGun> listElecGunByElecStationIdList(List<Long> elecStationIdList) {
        return elecGunMapper.listElecGunByElecStationIdList(elecStationIdList);
    }

    @Override
    public List<ElecGun> listElecGunByElecPileIdList(List<Long> elecPileIdList) {
        return elecGunMapper.listElecGunByElecPileIdList(elecPileIdList);
    }


    @Override
    public ElecGun selectGunByGunNo(String gunNo) {
        ElecGunExample elecGunExample = new ElecGunExample();
        elecGunExample.createCriteria().andGunNoEqualTo(gunNo);
        List<ElecGun> elecGuns = elecGunMapper.selectByExample(elecGunExample);
        if (elecGuns != null && elecGuns.size() > 0) {
            return elecGuns.get(0);
        } else {
            return null;
        }
    }

    @Override
    public TResponse saveOrUpdateElecGun(ElecGun elecGun, String tenantCode, String loginName) {
        ElecPile pileInfo = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
        Date date = new Date();
        elecGun.setTenantCode(tenantCode);
        elecGun.setLastUpdatedBy(loginName);
        elecGun.setLastUpdatedTime(date);
        elecGun.setElecStationId(pileInfo.getElecStationId()); //新增站点ID

        //桩编号
        String gunNum = "1";

        if (elecGun.getElecGunId() != null) {//编辑
            ElecGun gunInfo = elecGunMapper.selectByPrimaryKey(elecGun.getElecGunId());
            if (gunInfo == null) {
                return TResponse.FAIL("更新失败,请联系研发");
            }

            elecGun.setElecStationId(pileInfo.getElecStationId()); //新增站点ID，过渡
            elecGunMapper.updateByPrimaryKeySelective(elecGun);
        } else {//新建
            ElecGunExample gunExample = new ElecGunExample();
            gunExample.createCriteria().andElecPileIdEqualTo(elecGun.getElecPileId());
            List<ElecGun> lst = elecGunMapper.selectByExample(gunExample);
            if (lst.size() > 1) {
                return TResponse.FAIL("一个充电桩最多二个充电枪");
            } else {
                if (lst.size() == 1) {
                    gunNum = "2";
                }
                String newGunNo = null;
                ElecGun elecGunInfo = elecGunMapper.selectLastGunNo(tenantCode, elecGun.getElecPileId());
                if (elecGunInfo == null) {
                    //生成第一个桩编号
                    newGunNo = pileInfo.getPileNo() + "01";
                } else {
                    //自增桩编号
                    newGunNo = StringUtil.newNo(elecGunInfo.getGunNo(), 2);
                }
                ElecPile ep = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
                if (ep != null) {
                    elecGun.setOperatorId(ep.getOperatorId());
                }
                elecGun.setGunNo(newGunNo);
                elecGun.setGunNum(gunNum);//枪号

                //枪编号新增桩逻辑地址进行通讯连接
                elecGun.setPileRuta(NumberUtil.bin2HexStr(elecGun.getGunNo().getBytes()));
//                if ("1".equals(gunNum)) {
////                    elecGun.setPileRuta(NumberUtil.bin2HexStr(pileInfo.getPileRtua().getBytes()));
//                    elecGun.setPileRuta(NumberUtil.bin2HexStr(elecGun.getGunNo().getBytes()));
////                    elecGun.setPileRuta(pileInfo.getPileRtua()+" 31");
//                } else {
//                    String pileRtua = pileInfo.getPileRtua()+" 32";
//                    elecGun.setPileRuta(NumberUtil.bin2HexStr(pileRtua.getBytes()));
//                }


                ElecGunExample example = new ElecGunExample();
                example.createCriteria().andGunNoEqualTo(newGunNo);
                List<ElecGun> elecGuns = elecGunMapper.selectByExample(example);
                if (!CollectionUtils.isEmpty(elecGuns)) {
                    return TResponse.FAIL("生成充电枪编号异常,请联系研发");
                }
                elecGun.setCreatedBy(loginName);
                elecGun.setCreatedTime(date);
                elecGunMapper.insertSelective(elecGun);
            }

        }
        return TResponse.SUCCESS();
    }

    @Override
    public PageInfo<ElecGunMonitorVo> listPageByMonitor(ElecGunSearch elecGunSearch) {
        PageHelper.startPage(elecGunSearch.getOffset(), elecGunSearch.getLimit());
        List<ElecGunMonitorVo> elecGuns = elecGunMapper.listPageByMonitor(elecGunSearch);
        if (elecGuns.size() == 0) {
            return new PageInfo<ElecGunMonitorVo>(elecGuns);
        }

        Iterator<ElecGunMonitorVo> iterator = elecGuns.iterator();

        List<Long> gunIdList = new ArrayList<>();
        while (iterator.hasNext()) {
            ElecGunMonitorVo next = iterator.next();
            gunIdList.add(next.getElecGunId());
        }

        List<OrderInfoMonitorVo> orderInfos = orderInfoMapper.selectByGunIdList(gunIdList);
        while (iterator.hasNext()) {
            ElecGunMonitorVo next = iterator.next();
            for (OrderInfoMonitorVo orderResult : orderInfos) {
                if (orderResult.getElecGunId().longValue() == next.getElecGunId().longValue()) {

                    next.setSoc(orderResult.getSoc());  //soc
                    next.setOrderTime(orderResult.getLastTime()); //充满时间
                    next.setTotalMoney(orderResult.getPayAmount()); //金额
                    if (orderResult.getOccupyPayTime() != null) {
                        next.setOrderUpdateTime(orderResult.getOccupyPayTime()); //更新时间
                    } else {
                        next.setOrderUpdateTime(orderResult.getEndTime()); //更新时间
                    }
                    next.setOccupyTime(orderResult.getOccupyTime()); //占用时间
                    next.setSoc(orderResult.getSoc());
                    if ("1".equals(orderResult.getStatus())) {
                        //充电中
                        ElecPile elecPile = elecPileService.selectLastPileNo(next.getTenantCode(), next.getPileNo());
                        //总金额
                        BigDecimal amount = redChargeDataService.getAmount(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //soc
                        BigDecimal soc = redChargeDataService.getSoc(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //电流
                        BigDecimal elec = redChargeDataService.getElec(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //电压
                        BigDecimal vol = redChargeDataService.getVol(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //温度
                        String temperatureHigh = redChargeDataService.getTemperatureHigh(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //bms电流
                        BigDecimal demandElec = redChargeDataService.getDemandElec(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        //bms电压
                        BigDecimal demandVoltage = redChargeDataService.getDemandVoltage(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        next.setTotalMoney(amount);
                        next.setSoc(soc);
                        next.setElec(String.valueOf(elec));
                        next.setVoltage(String.valueOf(vol));
                        //功率=电流*电压/1000
                        next.setChargePower(String.valueOf(elec.multiply(vol).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_HALF_UP)));
                        next.setDemandElec(String.valueOf(demandElec));
                        next.setDemandVoltage(String.valueOf(demandVoltage));
                        //温度相同
                        next.setTemperature(temperatureHigh);
                        next.setBmsTemperature(temperatureHigh);

                        //更新时间
                        String chargeReportTime = redChargeDataService.getChargeReportTime(elecPile.getPileRtua(), next.getGunNum(), orderResult.getOrderNum());
                        if (chargeReportTime == null) {
                            next.setOrderUpdateTime(new Date());
                        } else {
                            Date date = DateHelper.stringToDate(chargeReportTime, DateHelper.DATE_COMMON_FORMAT);
                            next.setOrderUpdateTime(date);
                        }
                    }

                    break;
                }
            }
        }

        return new PageInfo<ElecGunMonitorVo>(elecGuns);
    }

    @Override
    public TResponse listPageLintChart(String stationNo, String type) {
        if (stationNo == null || stationNo.equals("")) {
            return TResponse.FAIL("站点名称不能为空");
        }

        List<ElecGunMonitorChartVo> list = new ArrayList<>();

        Calendar instance = Calendar.getInstance();

        //月度列表
        if ("1".equals(type)) {
            instance.add(Calendar.YEAR, -1);
            List<ElecGunMonitorChartVo> months = elecGunMapper.listChartByMonth(stationNo, instance.getTime());


            for (int i = 0; i < 12; i++) {
                int j = 0;
                instance.add(Calendar.MONTH, 1);
                String yyyyMMFormat = DateHelper.dataToString(instance.getTime(), "yyyy-MM");

                for (ElecGunMonitorChartVo month : months) {
                    //月份存在，则不变更
                    if (yyyyMMFormat.equals(month.getMonths())) {
                        j = 1;
                        break;
                    }
                }

                //填充空白数据
                if (j == 0) {
                    ElecGunMonitorChartVo elecGunMonitorChartVo = new ElecGunMonitorChartVo(type, instance.getTime());
                    months.add(elecGunMonitorChartVo);
                }


            }

            list.addAll(months.stream().sorted(Comparator.comparing(ElecGunMonitorChartVo::getMonths)).collect(Collectors.toList()));
        } else {
            //日列表
            int yearDay = instance.get(Calendar.DAY_OF_YEAR);
            instance.add(Calendar.MONTH, -1);
            int diff = yearDay - instance.get(Calendar.DAY_OF_YEAR);
            List<ElecGunMonitorChartVo> days = elecGunMapper.listChartByDay(stationNo, instance.getTime());


            for (int i = 0; i < diff; i++) {
                int j = 0;
                instance.add(Calendar.DAY_OF_YEAR, 1);
                String yyyyMMddFormat = DateHelper.dataToString(instance.getTime(), DateHelper.DATE_FORMAT_YYYY_MM_DD);

                for (ElecGunMonitorChartVo day : days) {
                    if (yyyyMMddFormat.equals(day.getDays())) {
                        j = 1;
                        break;
                    }
                }

                //填充空白数据
                if (j == 0) {
                    ElecGunMonitorChartVo elecGunMonitorChartVo = new ElecGunMonitorChartVo(type, instance.getTime());
                    days.add(elecGunMonitorChartVo);
                }
            }

            list.addAll(days.stream().sorted(Comparator.comparing(ElecGunMonitorChartVo::getDays)).collect(Collectors.toList()));
        }

        return TResponse.SUCCESS_DATA(list);
    }

    @Override
    public ElecPileStatusCountVo countGun(StatisticsSearch search) {
        return elecGunMapper.countGunInConsole(search);
    }

    @Override
    public void updateGunOperators(Long pileId, Long operatorId,Long elecStationId) {
        elecGunMapper.updateGunOperators(pileId, operatorId, elecStationId);
    }

    @Override
    public void updateOperatorBySId(ElecStation elecStation) {
        elecGunMapper.updateOperatorBySId(elecStation);
    }

    public static void main(String[] args) {
        List<ElecGunMonitorChartVo> list = new ArrayList<>();
        ElecGunMonitorChartVo elecGunMonitorChartVo1 = new ElecGunMonitorChartVo("0", new Date());
        ElecGunMonitorChartVo elecGunMonitorChartVo2 = new ElecGunMonitorChartVo("1", new Date());
        ElecGunMonitorChartVo elecGunMonitorChartVo3 = new ElecGunMonitorChartVo("5", new Date());
        ElecGunMonitorChartVo elecGunMonitorChartVo4 = new ElecGunMonitorChartVo("3", new Date());
        list.add(elecGunMonitorChartVo1);
        list.add(elecGunMonitorChartVo2);
        list.add(elecGunMonitorChartVo3);
        list.add(elecGunMonitorChartVo4);
        List<ElecGunMonitorChartVo> collect = list.stream().sorted(Comparator.comparing(ElecGunMonitorChartVo::getType)).collect(Collectors.toList());
        collect.stream().forEach(elecGunMonitorChartVo -> System.out.println(elecGunMonitorChartVo.getType()));
    }
}
